package com.wechat.page;

import java.util.concurrent.atomic.AtomicBoolean;

import com.swak.config.setting.Settings;
import com.swak.exception.RemotingException;
import com.swak.exception.StaleObjectStateException;
import com.swak.fx.support.Display;
import com.swak.fx.support.FXMLView;
import com.swak.fx.support.Splash;
import com.swak.fx.support.ui.UI;
import com.swak.fx.support.ui.UIAction;
import com.swak.fx.support.ui.UIIcon;
import com.swak.fx.support.ui.UIStackPane;
import com.swak.ui.Event;
import com.swak.ui.Events;
import com.wechat.login.Login;
import com.wechat.login.LoginService;
import com.wechat.network.Network;
import com.wechat.network.Networks;
import com.wechat.page.login.ModelSwitchComp;
import com.wechat.page.login.UserLoginComp;
import com.wechat.page.login.UserRegisterComp;
import com.wechat.page.login.UserSwitchComp;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;

/**
 * 登录
 * 
 * @author lifeng
 */
@FXMLView(title = "登录", value = "LoginPage.fxml", css = "LoginPage.css", stageStyle = "TRANSPARENT")
public class LoginPage extends Splash {

	private static final int ADJUST_SIZE = 10;

	// 标题
	private HBox titlePane;
	private Label title;
	private Pane placeholder;

	// 控制按钮
	private UIAction topBtn;
	private UIAction modelBtn;
	private UIAction minBtn;
	private UIAction closeBtn;

	// 内容面板
	private UIStackPane content;

	private UserLoginComp userLoginComp;
	private UserSwitchComp userSwitchComp;
	private UserRegisterComp userRegisterComp;
	private ModelSwitchComp modelSwitchComp;

	// 非模式选择的一个页面
	private Active nonModelActive = Active.Login;

	// 是否登录中
	private AtomicBoolean logining = new AtomicBoolean(false);

	public LoginPage(Stage stage) {
		super(stage, ADJUST_SIZE);
		this.setResizeAble(false);
		this.topBtn = new UIAction();
		this.modelBtn = new UIAction();
		this.minBtn = new UIAction();
		this.closeBtn = new UIAction();
		this.title = new Label(Display.getStage().getTitle());
		this.placeholder = new Pane();
		this.titlePane = new HBox();
		this.content = new UIStackPane();
	}

	@Override
	public void initializeParts() {
		super.initializeParts();
		this.initTitlePane();
		this.initContentPane();

		this.addChild(this.titlePane);
		GridPane.setConstraints(this.titlePane, 0, 0);
		GridPane.setHgrow(this.titlePane, Priority.ALWAYS);
		GridPane.setVgrow(this.titlePane, Priority.NEVER);

		this.addChild(this.content);
		GridPane.setConstraints(this.content, 0, 1);
		GridPane.setHgrow(this.content, Priority.ALWAYS);
		GridPane.setVgrow(this.content, Priority.ALWAYS);
	}

	private void initTitlePane() {
		this.topBtn.textNodeProperty().set(new UIIcon(UI.Icons.THUMB_TACK));
		this.modelBtn.textNodeProperty().set(new UIIcon(UI.Icons.SETTINGS));
		this.minBtn.textNodeProperty().set(new UIIcon(UI.Icons.MINUS));
		this.closeBtn.textNodeProperty().set(new UIIcon(UI.Icons.REMOVE));
		this.closeBtn.getStyleClass().add("close-btn");

		this.title.getStyleClass().add("title");
		this.titlePane.getStyleClass().add("title_pane");
		this.titlePane.getChildren().addAll(this.title, this.placeholder, this.topBtn, this.modelBtn, this.minBtn,
				this.closeBtn);
		HBox.setHgrow(this.placeholder, Priority.ALWAYS);
	}

	private void initContentPane() {
		this.content.getStyleClass().add("content_pane");
	}

	@Override
	public void setupEventHandlers() {
		super.setupEventHandlers();
		this.registerUIEvent(this.titlePane, UI.Events.Window_Drag);
		this.registerUIEvent(this.topBtn, UI.Events.Window_Fix);
		this.registerUIEvent(this.minBtn, UI.Events.Window_Min);
		this.registerUIEvent(this.closeBtn, UI.Events.Window_Close);
		this.registerUIEvent(this.titlePane, UI.Events.Window_Max2);
		this.registerUIEvent(this.placeholder, UI.Events.Window_Drag);

		// 控制所有的按钮的点击： 登录过程中不能点击任何按钮
		this.root.addEventFilter(MouseEvent.MOUSE_CLICKED, (e) -> {
			if (this.logining.get()) {
				e.consume();
			}
		});

		// 模式选择按钮
		this.modelBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, (e) -> {
			Active active = this.activeProperty.get();
			if (active != null && active == Active.Model) {
				this.activeProperty.set(this.nonModelActive);
			} else {
				this.activeProperty.set(Active.Model);
				this.nonModelActive = active;
			}
		});

		// 点击 切换用户
		this.$on("page:switch", (e) -> {
			this.activeProperty.set(Active.Switch);
		});

		// 点击 创建用户
		this.$on("page:register", (e) -> {
			this.activeProperty.set(Active.Register);
		});

		// 点击 登录
		this.$on("page:login", (e) -> {
			this.activeProperty.set(Active.Login);
		});

		// 执行登录
		this.$on("login", (e) -> {
			this.doLogin();
		});
	}

	private void showUserLoginComp() {
		this.$runOnUI(() -> {
			if (userLoginComp == null) {
				userLoginComp = this.NewComp(UserLoginComp.class);
			}
			this.content.switchTop(userLoginComp.getRoot());
		});
	}

	private void showUserSwitchComp() {
		this.$runOnUI(() -> {
			if (userSwitchComp == null) {
				userSwitchComp = this.NewComp(UserSwitchComp.class);
			}
			this.content.switchTop(userSwitchComp.getRoot());
		});
	}

	private void showUserRegisterComp() {
		this.$runOnUI(() -> {
			if (userRegisterComp == null) {
				userRegisterComp = this.NewComp(UserRegisterComp.class);
			}
			this.content.switchTop(userRegisterComp.getRoot());
		});
	}

	private void showModelComp() {
		this.$runOnUI(() -> {
			if (modelSwitchComp == null) {
				modelSwitchComp = this.NewComp(ModelSwitchComp.class);
			}
			this.content.switchTop(modelSwitchComp.getRoot());
		});
	}

	private void doLogin() {
		if (this.logining.compareAndExchange(false, true)) {
			return;
		}
		try {
			this.startRuntime();
			this.startNetwork();
			this.startProgress();
			this.startApp();
		} catch (Throwable e) {
			this.exitWithError(e);
		}
	}

	private void startRuntime() {
		Login login = LoginService.login();
		Settings.me().enableRuntime(login.getId());
	}

	private void startNetwork() throws RemotingException {
		Network network = Networks.New();
		network.connect();
		network.login();
	}

	@Override
	public void setupBindings() {
		super.setupBindings();
	}

	@Override
	public void setupValueChangedListeners() {
		super.setupValueChangedListeners();
		this.fixActiveProperty().addListener((ob, o, n) -> {
			if (n) {
				this.topBtn.getStyleClass().add("active");
			} else {
				this.topBtn.getStyleClass().remove("active");
			}
		});
		this.activeProperty().addListener((ob, o, n) -> {
			if (n == null || n == Active.Login) {
				this.showUserLoginComp();
			} else if (n == null || n == Active.Switch) {
				this.showUserSwitchComp();
			} else if (n == null || n == Active.Register) {
				this.showUserRegisterComp();
			} else if (n == null || n == Active.Model) {
				this.showModelComp();
			}
		});
		this.activeProperty().addListener((ob, o, n) -> {
			this.$runOnUI(() -> {
				if (n != null && n == Active.Model) {
					this.modelBtn.textNodeProperty().set(new UIIcon(UI.Icons.USER));
				} else {
					this.modelBtn.textNodeProperty().set(new UIIcon(UI.Icons.SETTINGS));
				}
			});
		});
	}

	@Override
	public void initializeFinish() {
		super.initializeFinish();

		// 基本的校验
		if (LoginService.me() == null) {
			this.exitWithError(new StaleObjectStateException("LoginSerive init error."));
			return;
		}

		// 设置登录账号
		this.activeProperty.set(Active.Login);
	}

	// ================================================================================
	// Properties
	// ================================================================================
	private BooleanProperty fixActiveProperty = new SimpleBooleanProperty(false);

	public BooleanProperty fixActiveProperty() {
		return fixActiveProperty;
	}

	private ObjectProperty<Active> activeProperty = new SimpleObjectProperty<LoginPage.Active>();

	public ObjectProperty<Active> activeProperty() {
		return activeProperty;
	}

	// ================================================================================
	// 状态监听
	// ================================================================================
	@Override
	public void windowStateChange(int state) {
		super.windowStateChange(state);
		this.fixActiveProperty().set((state & UI.States.Window_Fix.index) == UI.States.Window_Fix.index);
	}

	// ================================================================================
	// 重新定制启动流程
	// ================================================================================
	@Override
	protected void start() {
	}

	@Override
	public void close() {
		super.close();
		Events.post(Event.EXIT);
	}

	/**
	 * 激活的页面
	 * 
	 * @author 618lf
	 */
	enum Active {
		Login, Switch, Register, Model
	}
}
